package com.framework.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.framework.core.common.bo.LoginUser;
import com.framework.core.common.constant.Constants;
import com.framework.core.common.enums.UserPlatformEnum;
import com.framework.core.exception.CustomException;
import com.framework.core.log.annotation.AutoLog;
import com.framework.core.result.R;
import com.framework.core.util.StpAppUtil;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 在线用户管理
 *
 * @author Kevin
 */
@RestController
@RequestMapping("/system/monitor/online")
public class SysUserOnlineController {

    /**
     * 分页查询在线用户
     */
    @GetMapping("/selectSysUserOnlineWithPage")
    @SaCheckPermission("monitor:online:selectSysUserOnlineWithPage")
    @AutoLog(module = "在线用户", title = "分页查询在线用户")
    public R<Page<LoginUser>> selectSysUserOnlineWithPage(Page reqPage, String username, String userPlatform) {
        List<LoginUser> loginUserList = new ArrayList();
        List<String> keys = StpUtil.searchTokenValue("", -1, 0, true);
        for (String key : keys) {
            // token sample, Authorization:login:token:8734da0866f4440daeea3d836d5ecf8c
            String tokenValue = StrUtil.subAfter(key, StpUtil.getTokenName() + ":" + StpUtil.TYPE + ":token:", true);
            LoginUser item = (LoginUser) StpUtil.getTokenSessionByToken(tokenValue).get(Constants.LOGIN_USER_KEY);
            if (Objects.nonNull(item)) {
                if (StrUtil.isNotBlank(username) && StrUtil.isNotBlank(userPlatform)) {
                    if (StrUtil.contains(item.getUsername(), username) && item.getUserPlatform().equals(userPlatform)) {
                        loginUserList.add(item);
                    }
                } else if (StrUtil.isNotBlank(username)) {
                    if (StrUtil.contains(item.getUsername(), username)) {
                        loginUserList.add(item);
                    }
                } else if (StrUtil.isNotBlank(userPlatform)) {
                    if (item.getUserPlatform().equals(userPlatform)) {
                        loginUserList.add(item);
                    }
                } else {
                    loginUserList.add(item);
                }
            }
        }

        List<String> keys2 = StpAppUtil.searchTokenValue("", -1, 0, true);
        for (String key : keys2) {
            // token sample, Authorization:login:token:8734da0866f4440daeea3d836d5ecf8c
            String tokenValue = StrUtil.subAfter(key, StpAppUtil.getTokenName() + ":" + StpAppUtil.TYPE + ":token:", true);
            LoginUser item = (LoginUser) StpAppUtil.getTokenSessionByToken(tokenValue).get(Constants.LOGIN_USER_KEY);
            if (Objects.nonNull(item)) {
                if (StrUtil.isNotBlank(username) && StrUtil.isNotBlank(userPlatform)) {
                    if (StrUtil.contains(item.getUsername(), username) && item.getUserPlatform().equals(userPlatform)) {
                        loginUserList.add(item);
                    }
                } else if (StrUtil.isNotBlank(username)) {
                    if (StrUtil.contains(item.getUsername(), username)) {
                        loginUserList.add(item);
                    }
                } else if (StrUtil.isNotBlank(userPlatform)) {
                    if (item.getUserPlatform().equals(userPlatform)) {
                        loginUserList.add(item);
                    }
                } else {
                    loginUserList.add(item);
                }
            }
        }

        // 进行排序，以登陆时间倒序
        loginUserList = loginUserList.stream().sorted(Comparator.comparing(LoginUser::getLoginTime).reversed()).collect(Collectors.toList());

        Page<LoginUser> page = new Page<>(reqPage.getCurrent(), reqPage.getSize(), loginUserList.size());
        if (page.getPages() > 0) {
            int fromIndex = (int) ((page.getCurrent() - 1) * page.getSize());
            int toIndex = page.getCurrent() == page.getPages() ? (int) page.getTotal() : (int) (fromIndex + page.getSize());
            page.setRecords(loginUserList.subList(fromIndex, toIndex));
        }
        return R.success(page);
    }

    /**
     * 强制退出
     */
    @PostMapping("/forceLogout")
    @SaCheckPermission("monitor:online:forceLogout")
    @AutoLog(module = "在线用户", title = "强制退出")
    public R<Void> forceLogout(@RequestParam String userPlatform, @RequestParam String token) {
        if (Objects.equals(userPlatform, UserPlatformEnum.WEB.getCode())) {
            if (Objects.equals(StpUtil.getTokenValue(), token)) {
                throw new CustomException("强制退出，不能退出当前登录用户");
            }
            StpUtil.logoutByTokenValue(token);
        }
        if (Objects.equals(userPlatform, UserPlatformEnum.APP.getCode())) {
            StpAppUtil.logoutByTokenValue(token);
        }
        return R.success();
    }

}
